package com.project.shiro;

import com.project.bean.GradeBean;
import com.project.service.IGradeService;
import com.project.util.ShiroUtil;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.servlet.Filter;
import java.util.List;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Resource
    private IGradeService gradeService;
    /**
     * 配置securityManager
     * securityManager就是一个中央管理器
     * @return
     */
    @Bean
    public SecurityManager getSecurityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //将自定义的realm注入到securityManager里面。
        securityManager.setRealm(customRealm());
        //创建一个session仓库，并设置为不可创建session
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        //将session仓库放入主体持久中
        DefaultSubjectDAO defaultSubjectDAO = new DefaultSubjectDAO();
        defaultSubjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        //将自定义的主体注入到安全管理器中，这样的话，以后的主体都是自定义的，不能使用session
        securityManager.setSubjectDAO(defaultSubjectDAO);
        //将自定义的主体工厂注入到安全管理器中，
        securityManager.setSubjectFactory(this.getSubjectFactory());

        return securityManager;
    }
    @Bean
    public ShiroFilterFactoryBean getFilter(SecurityManager securityManager){
//        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 用自定义的FactoryBean来设置过滤器
        ShiroFilterFactoryBean shiroFilterFactoryBean = new RestShiroFilterFactoryBean();

        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();

        filters.put("perms", new RestAuthorizationFilter());
        filters.put("authc", new ShiroFormAuthenticationFilter());

        List<GradeBean> gradeBeanList  = gradeService.findAll();
        Map filterChainMap = ShiroUtil.loadFilterChainMap(gradeBeanList);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 开启aop注解支持
     * 即在controller中使用 @RequiresPermissions("user/userList")
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor attributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //设置安全管理器
        attributeSourceAdvisor.setSecurityManager(securityManager);
        return attributeSourceAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    //自动导入自定义的ShiroRealm
    @Bean
    public ShiroRealm customRealm(){
        return new ShiroRealm();
    }

    //自动导入自定义的默认主体工厂
    @Bean
    public JWTDefaultWebSubjectFactory getSubjectFactory(){
        return new JWTDefaultWebSubjectFactory();
    }
}
